package com.cn.stepLock;

import com.cn.stepLock.executeLambda.ConsumerLambda;
import com.google.common.collect.ImmutableList;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;

/**
 * @author Aaron
 * @desc
 * @createTime 2022-02-21 20:33
 * @since
 */
public class Main {

    public static Object object  = new Object();
    public static void main(String[] args) throws InterruptedException {
        System.out.println("hello world");
        //testNormal();
        testLock();
    }

    private static void testLock() throws InterruptedException {
        TestObject testObject = new TestObject();
        List<ConsumerLambda<TestObject, Object>> of = ImmutableList.of(new ConsumerLambda<>(x -> x.add(), testObject), new ConsumerLambda<>(x -> x.set(), testObject), new ConsumerLambda<>(x -> x.print(), testObject));
        ExecuteRequest executeRequest = new ExecuteRequest(of);
        ObjectStepLock testObjectObjectStepLock = new ObjectStepLock();
        CountDownLatch countDownLatch = new CountDownLatch(40);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                testObjectObjectStepLock.execute(executeRequest);
                countDownLatch.countDown();
            },"thread"+(i+1)).start();
        }
        Thread.sleep(200);
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                testObjectObjectStepLock.execute(executeRequest);
                countDownLatch.countDown();
            },"thread"+(i+21)).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("time:"+(System.currentTimeMillis()-startTime));
        testObjectObjectStepLock.stop();
    }

    private static void testNormal() {
        TestObject testObject = new TestObject();
        CountDownLatch countDownLatch = new CountDownLatch(20);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                synchronized(object) {
                    testObject.add();
                    testObject.set();
                    testObject.print();
                    countDownLatch.countDown();;
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("time:"+(System.currentTimeMillis()-startTime));
    }
}
